<template>
  <el-card>
    <el-form :inline="true" :model="searchForm" ref="searchFormRef">
      <el-form-item label="上级组织选择" prop="parentId">
        <OrganizationSelect v-model="searchForm.parentId" @change="onsetSelectedNode" />
      </el-form-item>
      <el-form-item label="组织名称" prop="filter">
        <el-input
          v-model="searchForm.filter"
          placeholder="请输入组织名称"
          :clearable="true"
          maxlength="256"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="onSearch">查询</el-button>
        <el-button icon="RefreshRight" @click="onReset(searchFormRef)">重置</el-button>
      </el-form-item>
    </el-form>
    <el-button type="primary" icon="Plus" @click="isAddDialogVisible = true">新增</el-button>
    <el-table
      :data="organizationData"
      :border="true"
      :stripe="true"
      class="table-data"
      row-key="id"
      :lazy="true"
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      @expand-change="onExpandChange"
    >
      <el-table-column type="index" label="序号" width="180" />
      <el-table-column prop="code" label="Code" />
      <el-table-column prop="displayName" label="名称" />
      <el-table-column label="操作">
        <template #default="scope">
          <el-button
            type="primary"
            @click="onUpdate(scope.row.id)"
            size="small"
            icon="Edit"
            title="修改"
            style="margin-left: 12px"
            >修改</el-button
          >
          <el-button
            type="default"
            size="small"
            icon="View"
            title="查看"
            @click="onDetail(scope.row.id)"
            >查看</el-button
          >
          <el-popconfirm
            :title="`你确定删除${scope.row.displayName}?`"
            @confirm="onRemove(scope.row.id)"
            width="200px"
          >
            <template #reference>
              <el-button type="danger" size="small" icon="Delete" title="删除">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:current-page="pageNo"
      v-model:page-size="pageSize"
      :page-sizes="[10, 15, 20, 50]"
      :background="true"
      layout="prev, pager, next, jumper,->,sizes,total"
      :total="total"
      @current-change="getOrganizationListAsync"
      @size-change="onSizeChange"
    />
  </el-card>

  <Show :visible="isAddDialogVisible">
    <OrganizationAdd
      v-model="isAddDialogVisible"
      @update:refresh="onRefresh"
      title="添加组织"
      max-height="500px"
    ></OrganizationAdd>
  </Show>
  <Show :visible="isUpdateDialogVisible">
    <OrganizationUpdate
      v-model="isUpdateDialogVisible"
      @update:refresh="onRefresh"
      title="修改组织"
      :id="updateId"
      max-height="500px"
    ></OrganizationUpdate>
  </Show>
  <Show :visible="isDetailDialogVisible">
    <OrganizationDetaile
      v-model="isDetailDialogVisible"
      :id="detailId"
      title="查看组织"
      max-height="500px"
    ></OrganizationDetaile>
  </Show>
</template>

<script lang="ts" setup>
import { Show } from '@/components/show/index';
import { OrganizationAdd } from './add/index';
import { OrganizationUpdate } from './update/index';
import { OrganizationDetaile } from './detail/index';
import { OrganizationSelect } from './select/index';
import { ref, onMounted } from 'vue';
import { getListAsync, getTreeAsync, deleteAsync } from '@/utils/api/organization/index';
import type { FormInstance, TreeNode } from 'element-plus';
import type { GetOrganizationsInput, OrganizationTreeDto } from '@/utils/api/organization/type';
import type { PagedResultDto } from '@/utils/api/type';

// 默认页大小
const defaultPageSize: number = 10;
// 查询条件参数
const searchFormRef = ref<FormInstance>();
const searchForm = ref<GetOrganizationsInput>({
  skipCount: 0,
  maxResultCount: defaultPageSize
});
// 列表数据
let organizationData = ref<OrganizationTreeDto[]>([]);
// 分页器默认页码
let pageNo = ref<number>(1);
// 每一页展示几条数据
let pageSize = ref<number>(defaultPageSize);
// 存储已有总个数
let total = ref<number>(0);

// 是否显示add dialogVisible
let isAddDialogVisible = ref(false);

// 是否显示updte dialogVisible
let isUpdateDialogVisible = ref(false);
let updateId = ref<string>();

// 是否显示detail dialogVisible
let isDetailDialogVisible = ref(false);
let detailId = ref<string>();

// 详情
const onDetail = (id: string) => {
  isDetailDialogVisible.value = true;
  detailId.value = id;
};

// 修改
const onUpdate = (id: string) => {
  isUpdateDialogVisible.value = true;
  updateId.value = id;
};

// 删除
const onRemove = async (id: string) => {
  await deleteAsync(id);
  // 删除成功刷新页面
  await onRefresh();
};

// 组织选择后的业务逻辑
const onsetSelectedNode = (val: any) => {
  searchForm.value.parentId = val[val.length - 1];
};

// 查询
const onSearch = async () => {
  await getOrganizationListAsync();
};

// 刷新
const onRefresh = async () => {
  await getOrganizationListAsync();
};

//分页器下拉菜单发生变化触发
const onSizeChange = async (pageSizes: number) => {
  pageSize.value = pageSizes;
  await getOrganizationListAsync();
};

// 重置
const onReset = (formEl: FormInstance | undefined) => {
  if (!formEl) {
    return;
  }
  formEl.resetFields();
};

//组件挂载完毕
onMounted(async () => {
  await getOrganizationListAsync();
});

// 查询列表
const getOrganizationListAsync = async (pager = 1) => {
  pageNo.value = pager;
  searchForm.value.maxResultCount = pageSize.value;
  searchForm.value.skipCount = (pageNo.value - 1) * pageSize.value;
  let result: PagedResultDto<OrganizationTreeDto> = await getListAsync(searchForm.value);
  total.value = result.totalCount;
  organizationData.value = result.items;
};

// load
// 定于属性table树类型
interface TableTreeRefreshTool {
  id: string;
  resolve: (date: OrganizationTreeDto[]) => void;
  expandCount: number;
  prevStatus?: boolean;
  treeNode: TreeNode;
}
let tableTreeRefreshTool = ref<Map<string, TableTreeRefreshTool>>(new Map());
const load = async (
  row: OrganizationTreeDto,
  treeNode: TreeNode,
  resolve: (date: OrganizationTreeDto[]) => void
): Promise<void> => {
  // 保存数据
  tableTreeRefreshTool.value.set(row.id, {
    id: row.id,
    resolve: resolve,
    expandCount: 0,
    treeNode: treeNode
  });

  const childOrganizationDto: OrganizationTreeDto[] = await getTreeAsync(row.id);
  resolve(childOrganizationDto);
};

// 展开树 从新加载子节点
const onExpandChange = async (row: OrganizationTreeDto, expanded: boolean) => {
  // 获取到之前保存的全局变量
  const curr = tableTreeRefreshTool.value.get(row.id);
  if (!curr) {
    return;
  }
  // 展开次数 +1
  curr.expandCount++;
  // 如果是展开状态，且展开次数大于1，且上一次的状态为折叠，则请求api数据，更新子菜单
  if (expanded && curr.expandCount > 1 && !curr.prevStatus) {
    const childOrganizationDto: OrganizationTreeDto[] = await getTreeAsync(row.id);
    // 调用之前存储的resolve方法
    curr.resolve(childOrganizationDto);
  }
  // 保存本次的展开或折叠状态，用于下次判断
  curr.prevStatus = expanded;
};
</script>
<style scoped lang="scss">
.table-data {
  width: 100%;
  margin: 20px 0;
}
</style>
